using System;

using Microsoft.Cci;
using Microsoft.FxCop.Sdk.Introspection;

namespace Tyng.Rules
{
	public abstract class MethodInstructionRuleBase<T> : MethodRuleBase<T>
        where T : MethodInstructionRuleBase<T>
	{
		private OpCode[] _opCodes;

		protected MethodInstructionRuleBase(params OpCode[] opCodesToCheck)
		{
			if(opCodesToCheck == null || opCodesToCheck.Length == 0)
				_opCodes = null;

			_opCodes = opCodesToCheck;
		}

		protected sealed override ProblemCollection Check(Method method)
		{
			InstructionList instructions = method.Instructions;
			
			for(int i = 0; i < instructions.Length; i++)
			{
				//if no op codes specified, check every instruction
				if(_opCodes == null)
				{
					CheckInstruction(instructions[i], method);
				}
				else
				{
					//check specific opcodes
					for(int j = 0; j < _opCodes.Length; j++)
					{
						if(_opCodes[j] == instructions[i].OpCode)
						{
							CheckInstruction(instructions[i], method);
							break;
						}
					}
				}
			}

			if(Problems.Count > 0)
				return Problems;
			else
				return null;
		}

		protected abstract void CheckInstruction(Instruction instruction, Method method);	
	}
}
